#ifndef STX_UNINITIALIZED_HPP
#define STX_UNINITIALIZED_HPP

#include <stx/core.hpp>

namespace stx {

template<typename T>
class uninitialized
{
public:
    
    typedef uninitialized<T> this_type;
    typedef T value_type;
    typedef T* pointer;
    typedef const T* const_pointer;
    typedef T& reference;
    typedef const T& const_reference;
    
    uninitialized()
    {
    }
    
    uninitialized(const T& x)
    {
        get() = x;
    }
    
    uninitialized(const uninitialized<T>& x)
    {
        get() = x.get();
    }
    
    void construct()
    {
        new(buf_) T;
    }
    
    void construct(const T& x)
    {
        new(buf_) T(x);
    }
    
    void destruct()
    {
        get().~T();
    }
    
    T& get()
    {
        return *(reinterpret_cast<T*>(buf_));
    }
    
    const T& get() const
    {
        return *(reinterpret_cast<const T*>(buf_));
    }
    
    T* get_ptr()
    {
        return reinterpret_cast<T*>(buf_);
    }
    
    const T* get_ptr() const
    {
        return reinterpret_cast<const T*>(buf_);
    }
    
private:
    
    union {
        char alignment_[alignment_of<T>::value];
        char buf_[sizeof(T)];
    };
};

} // namespace stx

#endif // STX_UNINITIALIZED_HPP
